import urllib
import re
import time
import os
import fnmatch
import datetime

URL_ADDRESS_FOREIGN = "http://www.moneydj.com/Z/ZE/ZEE/ZEE.djhtm"
URL_ADDRESS_SELF = "http://www.moneydj.com/Z/ZE/ZEF/ZEF.djhtm"
URL_ADDRESS_INVEST = "http://www.moneydj.com/Z/ZE/ZES/ZES.djhtm"
COMMENT_LINE_CHAR = "#"
SEPERATE_CHAR = "\t\t"

def getPrice(id):
	handle = urllib.urlopen("http://tw.stock.yahoo.com/q/q?s=%d" % id)
	for line in handle.readlines():
		if "</b></td>" in line:
			r = re.search(r"[0-9]+\.[0-9]+", line)
			return r.group()

def IsPositive(num):
	return num > 0

def IsNegative(num):
	return num < 0

def IsZero(num):
	return num == 0

def IsFileExist(pattern):
	for file in os.listdir(os.curdir):
		if fnmatch.fnmatch(file, pattern):
			return True
	return False

def GetPreviousFileName(date_str):	# date format : "0502"	
	day = datetime.timedelta(days=1)
	month_val = int(date_str[:2])
	day_val = int(date_str[2:])
	
	this_day = datetime.date.today()
	for i in xrange(10):
		this_day = this_day - day
		filename = "data%02d%02d.txt" % (this_day.month, this_day.day)
		
		if IsFileExist(filename):
			if this_day.month == month_val and this_day.day == day_val:
				continue
			else:
				return filename
	
	return None

############
# Data Row #
############

class Summary:
	def __init__(self, id=None):
		self.id = None
		self.straight = 0
		self.last_change = 0
		self.trade_count = 0
		self.total = 0

class ForeignData:
	def __init__(self):
		self.id = None
		self.name = None
		self.trade_count = None
		self.own_count = None
		self.own_rate = None

class DomesticData:
	def __init__(self):
		self.id = None
		self.name = None
		self.buy_count = None
		self.sell_count = None
		self.diff_count = None

#########
# Table #
#########

class SummaryTable:
	def __init__(self):
		self.table = {}		# self.table = { id : Summary() }
	
	def addData(self, id, trade_count):
		data = Summary()
		
		data.id = id
		if IsZero(trade_count):
			data.straight = 0
		elif IsPositive(trade_count):
			data.straight = 1
		else:
			data.straight = -1
		data.last_change = 0
		data.trade_count = trade_count
		data.total = data.straight
		
		self.table[data.id] = data
	
	def updataData(self, id, trade_count):
		data = self.table[id]
		if IsZero(trade_count):
			pass
		elif IsPositive(data.straight) and IsPositive(trade_count):
			data.straight += 1
			data.total += 1
		elif IsPositive(data.straight) and IsNegative(trade_count):
			data.last_change = data.straight
			data.straight = -1
			data.total -= 1
		elif IsNegative(data.straight) and IsPositive(trade_count):
			data.last_change = data.straight
			data.straight = 1
			data.total += 1
		elif IsNegative(data.straight) and IsNegative(trade_count):
			data.straight -= 1
			data.total -= 1
		elif IsZero(data.straight) and IsPositive(trade_count):
			data.straight += 1
			data.total += 1
		elif IsZero(data.straight) and IsNegative(trade_count):
			data.straight -= 1
			data.total -= 1
		
		data.trade_count = trade_count
		
		self.table[id] = data

class ForeignSummary(SummaryTable):
	def __init__(self):
		SummaryTable.__init__(self)	# self.table = { id : Summary() }
	
	def summary(self, trade_table):
		for id, trade_data in trade_table.iteritems():
			if self.table.has_key(id):
				self.updataData(id, trade_data.trade_count)
			else:
				self.addData(id, trade_data.trade_count)

class DomesticSummary(SummaryTable):
	def __init__(self):
		SummaryTable.__init__(self)		# self.table = { id : Summary() }
	
	def summary(self, trade_table):
		for id, trade_data in trade_table.iteritems():
			if self.table.has_key(id):
				self.updataData(id, trade_data.diff_count)
			else:
				self.addData(id, trade_data.diff_count)

class TradeTable:
	def __init__(self):
		self.table = {}

class ForeignTrade(TradeTable):
	def __init__(self):
		TradeTable.__init__(self)	# { id : ForeignData() }

	def parse(self, html_src):
		for i, line in enumerate(html_src):
			# find string like this : GenLink2stk('AP0050','xxxx');
			if "GenLink2stk" in line:
				name_text = line			# GenLink2stk('AP0050','xxxx');
				trade_text = html_src[i+5]	# <td class="t3n1">168</td>
				own_text = html_src[i+6]	# <td class="t3n1">300,664</td>
				rate_text = html_src[i+7]	# <td class="t3n1">60.13%</td>
				
				data = ForeignData()
				
				# GenLink2stk('AP0050','xxxx');
				name_search = re.search(r"'(?P<id>[A-Z0-9]+)','(?P<name>.+)'\);", name_text)
				if name_search:
					data.id = name_search.group("id")
					data.name = name_search.group("name")
				else:
					print "id or name error, org text : %s" % name_text
					continue
				
				# <td class="t3n1">168</td>
				trade_search = re.search(r">(?P<trade>[\-0-9,]+)<\/td>", trade_text)
				if trade_search:
					data.trade_count = int(trade_search.group("trade").replace(",", ""))
				else:
					data.trade_count = 0
				
				# <td class="t3n1">300,664</td>
				own_search = re.search(r">(?P<own>[\-0-9,]+)<\/td>", own_text)
				if own_search:
					data.own_count = int(own_search.group("own").replace(",", ""))
				else:
					data.own_count = 0
				
				# <td class="t3n1">60.13%</td>
				rate_search = re.search(r">(?P<rate>[0-9\.%]+)<\/td>", rate_text)
				if rate_search:
					data.own_rate = float(rate_search.group("rate").replace("%", ""))
				else:
					data.own_rate = 0.0
				
				self.table[data.id] = data

class DomesticTrade(TradeTable):
	def __init__(self):
		TradeTable.__init__(self)	# { id : DomesticData() }
	
	def parse(self, html_src):
		for i, line in enumerate(html_src):
			# find string like this : GenLink2stk('AP0050','xxxx');
			if "GenLink2stk" in line:
				name_text = line			# GenLink2stk('AP0050','xxxx');
				buy_text = html_src[i+5]	# <td class="t3n1">168</td>
				sell_text = html_src[i+6]	# <td class="t3n1">300,664</td>
				diff_text = html_src[i+7]	# <td class="t3n1">60.13%</td>
				
				data = DomesticData()
				
				# GenLink2stk('AP0050','xxxx');
				name_search = re.search(r"'(?P<id>[A-Z0-9]+)','(?P<name>.+)'\);", name_text)
				if name_search:
					data.id = name_search.group("id")
					data.name = name_search.group("name")
				else:
					print "id or name error, org text : %s" % name_text
					continue
				
				# <td class="t3n1">168</td>
				buy_search = re.search(r">(?P<buy>[\-0-9,]+)<\/td>", buy_text)
				if buy_search:
					data.buy_count = int(buy_search.group("buy").replace(",", ""))
				else:
					data.buy_count = 0
				
				# <td class="t3n1">300,664</td>
				sell_search = re.search(r">(?P<sell>[\-0-9,]+)<\/td>", sell_text)
				if sell_search:
					data.sell_count = int(sell_search.group("sell").replace(",", ""))
				else:
					data.sell_count = 0
				
				# <td class="t3n1">60.13%</td>
				diff_search = re.search(r">(?P<diff>[\-0-9,]+)<\/td>", diff_text)
				if diff_search:
					data.diff_count = int(diff_search.group("diff").replace(",", ""))
				else:
					data.diff_count = 0
				
				self.table[data.id] = data

##############
# Main Class #
##############

class DJMoneyParser():
	def __init__(self):
		self.date_str = None	# date format : "0502"
		self.table_foreign = ForeignTrade()
		self.table_self = DomesticTrade()
		self.table_invest = DomesticTrade()
	
	def getHtml(self, url):
		handle = urllib.urlopen(url)
		return handle.readlines()
	
	def getDate(self, html_list):
		date_list = []
		for html_src in html_list:
			for i, line in enumerate(html_src):
				# find string like this : <div class="t11">xxxxx: 02/29</div>
				if "t11" in line:
					date_search = re.search(r"(?P<month>[0-9]+)/(?P<day>[0-9]+)", line)
					date_str = date_search.group("month") + date_search.group("day")
					date_list.append(date_str)
					break
		
		# same date
		if len(set(date_list)) == 1 and date_list[0] != "":
			return date_list[0]
		else:
			raise "date error !!"
	
	def parse(self):
		html_foreign = self.getHtml(URL_ADDRESS_FOREIGN)
		html_self = self.getHtml(URL_ADDRESS_SELF)
		html_invest = self.getHtml(URL_ADDRESS_INVEST)
		
		self.date_str = self.getDate([html_foreign, html_self, html_invest])
		
		self.table_foreign.parse(html_foreign)
		self.table_self.parse(html_self)
		self.table_invest.parse(html_invest)

class SummaryDataMgr:
	def __init__(self):
		self.summary_foreign = ForeignSummary()
		self.summary_self = DomesticSummary()
		self.summary_invest = DomesticSummary()
	
	def readFile(self, filename):
		f = open(filename, "r")
		
		try:
			for line in f.readlines():
				# skip empty line and comment
				if line and line[0] == COMMENT_LINE_CHAR:
					continue
				
				result = re.split("[ |\n]+", line)
				
				id = result[1]
				data_f = Summary()
				data_f.id = id
				data_f.straight = int(result[2])
				data_f.last_change = int(result[3])
				data_f.total = int(result[4])
				data_f.trade_count = int(result[5])
				self.summary_foreign.table[id] = data_f
				
				data_s = Summary()
				data_s.id = id
				data_s.straight = int(result[6])
				data_s.last_change = int(result[7])
				data_s.total = int(result[8])
				data_s.trade_count = int(result[9])
				self.summary_self.table[id] = data_s
				
				data_i = Summary()
				data_i.id = id
				data_i.straight = int(result[10])
				data_i.last_change = int(result[11])
				data_i.total = int(result[12])
				data_i.trade_count = int(result[13])
				self.summary_invest.table[id] = data_i
		except:
			f.close()
			raise "open file fail !!"
		
		f.close()
	
	def writeFile(self, filename):
		f = open(filename, "w")
		
		id_total = []
		id_total.extend(self.summary_foreign.table.keys())
		id_total.extend(self.summary_self.table.keys())
		id_total.extend(self.summary_invest.table.keys())
		id_list = list(set(id_total))
		
		for id in id_list:
			data_f = self.summary_foreign.table[id] if self.summary_foreign.table.has_key(id) else Summary(id)
			data_s = self.summary_self.table[id] if self.summary_self.table.has_key(id) else Summary(id)
			data_i = self.summary_invest.table[id] if self.summary_invest.table.has_key(id) else Summary(id)
			s = "| %8s | %6s%6s%6s%9s | %6s%6s%6s%9s | %6s%6s%6s%9s |\n" % (id, data_f.straight, data_f.last_change, data_f.total, data_f.trade_count,
																				data_s.straight, data_s.last_change, data_s.total, data_s.trade_count,
																				data_i.straight, data_i.last_change, data_i.total, data_i.trade_count)
			f.write(s)
		
		f.close()
	
	def process(self):
		parser = DJMoneyParser()
		print "parsing htmls"
		parser.parse()
		
		previous_file = GetPreviousFileName(parser.date_str)
		if previous_file:
			print "reading file : %s" % previous_file
			self.readFile(previous_file)
		else:
			print "file not found"
		
		print "processing data ..."
		self.summary_foreign.summary(parser.table_foreign.table)
		self.summary_self.summary(parser.table_self.table)
		self.summary_invest.summary(parser.table_invest.table)
		
		cur_file = "data%s.txt" % parser.date_str
		print "saving file : %s" % cur_file
		self.writeFile(cur_file)
		
		print "completed"

########
# Main #
########

#if __name__ == "__main__":
#	print "123"

dataMgr = SummaryDataMgr()
dataMgr.process()
time.sleep(10)